#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
练习题24: 多重继承和MRO(方法解析顺序)深度实践

本练习深入探讨Python的多重继承机制和方法解析顺序(MRO)，
包括钻石继承问题、super()的使用、mixin模式等高级特性。

知识点:
- 多重继承基础
- 方法解析顺序(MRO) - C3线性化算法
- super()函数的正确使用
- 钻石继承问题和解决方案
- Mixin模式设计
- 抽象基类和接口设计
- 协作继承和方法链
- 多重继承的最佳实践
"""

import abc
from typing import Any, List, Dict, Optional, Protocol
from functools import wraps


class Animal:
    """
    练习1: 基础动物类 - 多重继承的根类
    """
    
    def __init__(self, name: str, species: str):
        self.name = name
        self.species = species
        print(f"Animal.__init__: {name} ({species})")
    
    def speak(self) -> str:
        """动物发声"""
        return f"{self.name} makes a sound"
    
    def move(self) -> str:
        """动物移动"""
        return f"{self.name} moves"
    
    def __str__(self) -> str:
        return f"{self.__class__.__name__}({self.name})"


class Mammal(Animal):
    """
    哺乳动物类
    """
    
    def __init__(self, name: str, species: str, fur_color: str = "brown"):
        super().__init__(name, species)
        self.fur_color = fur_color
        print(f"Mammal.__init__: fur_color={fur_color}")
    
    def nurse_young(self) -> str:
        """哺育幼崽"""
        return f"{self.name} nurses its young"
    
    def move(self) -> str:
        """哺乳动物移动方式"""
        return f"{self.name} walks on land"


class Bird(Animal):
    """
    鸟类
    """
    
    def __init__(self, name: str, species: str, wing_span: float = 1.0):
        super().__init__(name, species)
        self.wing_span = wing_span
        print(f"Bird.__init__: wing_span={wing_span}")
    
    def fly(self) -> str:
        """飞行"""
        return f"{self.name} flies with {self.wing_span}m wingspan"
    
    def move(self) -> str:
        """鸟类移动方式"""
        return f"{self.name} flies in the sky"
    
    def speak(self) -> str:
        """鸟类发声"""
        return f"{self.name} chirps"


class Aquatic:
    """
    练习2: 水生动物Mixin - 演示Mixin模式
    
    Mixin类提供特定功能，不应该单独实例化
    """
    
    def __init__(self, *args, **kwargs):
        # 调用下一个类的__init__
        super().__init__(*args, **kwargs)
        print(f"Aquatic.__init__: Adding aquatic abilities")
    
    def swim(self) -> str:
        """游泳能力"""
        return f"{self.name} swims in water"
    
    def dive(self, depth: float = 10.0) -> str:
        """潜水能力"""
        return f"{self.name} dives to {depth}m depth"
    
    def move(self) -> str:
        """水生动物移动方式"""
        # TODO: 实现水生动物的移动方式
        # 提示: 可以结合super()调用父类方法
        pass


class Flying:
    """
    飞行能力Mixin
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print(f"Flying.__init__: Adding flying abilities")
    
    def take_off(self) -> str:
        """起飞"""
        return f"{self.name} takes off"
    
    def land(self) -> str:
        """降落"""
        return f"{self.name} lands"
    
    def fly_to(self, destination: str) -> str:
        """飞往目的地"""
        return f"{self.name} flies to {destination}"


class Domesticated:
    """
    驯化动物Mixin
    """
    
    def __init__(self, *args, owner: str = "Unknown", **kwargs):
        super().__init__(*args, **kwargs)
        self.owner = owner
        print(f"Domesticated.__init__: owner={owner}")
    
    def obey_command(self, command: str) -> str:
        """服从命令"""
        return f"{self.name} obeys command: {command}"
    
    def show_affection(self) -> str:
        """表达感情"""
        return f"{self.name} shows affection to {self.owner}"


class Bat(Mammal, Flying):
    """
    练习3: 蝙蝠类 - 多重继承示例
    
    蝙蝠既是哺乳动物又能飞行
    """
    
    def __init__(self, name: str, species: str = "bat", **kwargs):
        # TODO: 正确调用父类初始化方法
        # 提示: 使用super()确保所有父类都被正确初始化
        pass
    
    def echolocate(self) -> str:
        """回声定位"""
        return f"{self.name} uses echolocation"
    
    def speak(self) -> str:
        """蝙蝠发声"""
        # TODO: 实现蝙蝠的发声方式
        # 提示: 可以结合父类的方法
        pass
    
    def move(self) -> str:
        """蝙蝠移动方式"""
        # TODO: 实现蝙蝠的移动方式
        # 提示: 蝙蝠主要通过飞行移动
        pass


class Dolphin(Mammal, Aquatic):
    """
    海豚类 - 水生哺乳动物
    """
    
    def __init__(self, name: str, species: str = "dolphin", **kwargs):
        # TODO: 正确初始化多重继承
        pass
    
    def echolocate(self) -> str:
        """声纳定位"""
        return f"{self.name} uses sonar"
    
    def speak(self) -> str:
        """海豚发声"""
        # TODO: 实现海豚的发声方式
        pass
    
    def perform_trick(self, trick: str) -> str:
        """表演技巧"""
        return f"{self.name} performs {trick}"


class Duck(Bird, Aquatic):
    """
    鸭子类 - 既能飞又能游泳的鸟类
    """
    
    def __init__(self, name: str, species: str = "duck", **kwargs):
        # TODO: 正确初始化多重继承
        pass
    
    def quack(self) -> str:
        """鸭子叫声"""
        return f"{self.name} quacks"
    
    def speak(self) -> str:
        """鸭子发声"""
        # TODO: 实现鸭子的发声方式
        pass


class Dog(Mammal, Domesticated):
    """
    狗类 - 驯化的哺乳动物
    """
    
    def __init__(self, name: str, breed: str = "mixed", **kwargs):
        self.breed = breed
        # TODO: 正确初始化多重继承
        pass
    
    def bark(self) -> str:
        """狗叫"""
        return f"{self.name} barks"
    
    def speak(self) -> str:
        """狗发声"""
        # TODO: 实现狗的发声方式
        pass
    
    def fetch(self, item: str) -> str:
        """捡取物品"""
        return f"{self.name} fetches {item}"


class Penguin(Bird, Aquatic):
    """
    练习4: 企鹅类 - 不会飞的鸟类，但会游泳
    
    演示方法重写和MRO的复杂情况
    """
    
    def __init__(self, name: str, species: str = "penguin", **kwargs):
        # TODO: 正确初始化多重继承
        pass
    
    def fly(self) -> str:
        """企鹅不会飞"""
        # TODO: 重写飞行方法
        # 提示: 企鹅不会飞，但可以"在水中飞行"
        pass
    
    def move(self) -> str:
        """企鹅移动方式"""
        # TODO: 实现企鹅的移动方式
        # 提示: 企鹅在陆地上走路，在水中游泳
        pass
    
    def slide_on_belly(self) -> str:
        """腹部滑行"""
        return f"{self.name} slides on its belly"


class MROAnalyzer:
    """
    练习5: MRO分析器 - 分析类的方法解析顺序
    
    要求:
    1. 显示类的MRO
    2. 分析方法调用路径
    3. 检测潜在的问题
    4. 提供优化建议
    """
    
    @staticmethod
    def show_mro(cls: type) -> None:
        """显示类的MRO"""
        # TODO: 实现MRO显示
        # 提示: 使用cls.__mro__或cls.mro()
        pass
    
    @staticmethod
    def analyze_method_resolution(cls: type, method_name: str) -> None:
        """分析方法解析路径"""
        # TODO: 实现方法解析分析
        # 提示: 遍历MRO，查找方法定义
        pass
    
    @staticmethod
    def find_diamond_inheritance(cls: type) -> List[type]:
        """查找钻石继承"""
        # TODO: 实现钻石继承检测
        # 提示: 检查MRO中是否有重复的基类
        pass
    
    @staticmethod
    def suggest_improvements(cls: type) -> List[str]:
        """建议改进"""
        # TODO: 实现改进建议
        # 提示: 基于MRO分析提供建议
        pass


class CooperativeClass:
    """
    练习6: 协作类 - 演示正确的super()使用
    
    协作继承确保所有类的方法都被调用
    """
    
    def __init__(self, *args, **kwargs):
        # TODO: 实现协作初始化
        # 提示: 使用super()并传递所有参数
        pass
    
    def process(self, data: Any) -> Any:
        """处理数据"""
        # TODO: 实现协作处理
        # 提示: 处理数据并调用super().process()
        pass


class LoggingMixin:
    """
    日志记录Mixin
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._log = []
    
    def log_action(self, action: str) -> None:
        """记录动作"""
        self._log.append(f"{self.__class__.__name__}: {action}")
    
    def get_log(self) -> List[str]:
        """获取日志"""
        return self._log.copy()
    
    def process(self, data: Any) -> Any:
        """带日志的处理"""
        self.log_action(f"Processing: {data}")
        result = super().process(data)
        self.log_action(f"Result: {result}")
        return result


class ValidationMixin:
    """
    验证Mixin
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
    
    def validate_data(self, data: Any) -> bool:
        """验证数据"""
        # TODO: 实现数据验证
        # 提示: 基本的数据验证逻辑
        pass
    
    def process(self, data: Any) -> Any:
        """带验证的处理"""
        if not self.validate_data(data):
            raise ValueError(f"Invalid data: {data}")
        return super().process(data)


class CachingMixin:
    """
    缓存Mixin
    """
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._cache = {}
    
    def get_cache_key(self, data: Any) -> str:
        """获取缓存键"""
        # TODO: 实现缓存键生成
        pass
    
    def process(self, data: Any) -> Any:
        """带缓存的处理"""
        cache_key = self.get_cache_key(data)
        if cache_key in self._cache:
            return self._cache[cache_key]
        
        result = super().process(data)
        self._cache[cache_key] = result
        return result


class DataProcessor(CooperativeClass, LoggingMixin, ValidationMixin, CachingMixin):
    """
    练习7: 数据处理器 - 多重继承的实际应用
    
    结合多个Mixin实现复杂功能
    """
    
    def __init__(self, name: str, *args, **kwargs):
        self.name = name
        super().__init__(*args, **kwargs)
    
    def process(self, data: Any) -> Any:
        """核心处理逻辑"""
        # TODO: 实现核心处理逻辑
        # 提示: 这是处理链的最后一环
        pass
    
    def __str__(self) -> str:
        return f"DataProcessor({self.name})"


def demonstrate_multiple_inheritance():
    """
    演示多重继承和MRO
    """
    print("=== 多重继承和MRO演示 ===")
    
    # 演示基本多重继承
    print("\n1. 基本多重继承演示:")
    try:
        # 创建各种动物
        bat = Bat("Bruce", fur_color="black")
        dolphin = Dolphin("Flipper", fur_color="gray")
        duck = Duck("Donald", wing_span=0.8)
        dog = Dog("Buddy", breed="Golden Retriever", owner="Alice")
        penguin = Penguin("Pingu")
        
        animals = [bat, dolphin, duck, dog, penguin]
        
        for animal in animals:
            print(f"\n{animal}:")
            print(f"  说话: {animal.speak()}")
            print(f"  移动: {animal.move()}")
            
            # 测试特殊能力
            if hasattr(animal, 'fly'):
                print(f"  飞行: {animal.fly()}")
            if hasattr(animal, 'swim'):
                print(f"  游泳: {animal.swim()}")
            if hasattr(animal, 'obey_command'):
                print(f"  服从: {animal.obey_command('sit')}")
    
    except Exception as e:
        print(f"多重继承演示出错: {e}")
    
    # 演示MRO分析
    print("\n2. MRO分析:")
    try:
        classes_to_analyze = [Bat, Dolphin, Duck, Dog, Penguin, DataProcessor]
        
        for cls in classes_to_analyze:
            print(f"\n{cls.__name__} MRO:")
            MROAnalyzer.show_mro(cls)
            
            # 分析特定方法
            if hasattr(cls, 'move'):
                MROAnalyzer.analyze_method_resolution(cls, 'move')
    
    except Exception as e:
        print(f"MRO分析出错: {e}")
    
    # 演示协作继承
    print("\n3. 协作继承演示:")
    try:
        processor = DataProcessor("TestProcessor")
        
        # 测试处理功能
        test_data = ["hello", "world", "hello"]  # 包含重复数据测试缓存
        
        for data in test_data:
            result = processor.process(data)
            print(f"处理 '{data}' -> '{result}'")
        
        # 显示日志
        print(f"\n处理日志:")
        for log_entry in processor.get_log():
            print(f"  {log_entry}")
    
    except Exception as e:
        print(f"协作继承演示出错: {e}")
    
    # 演示钻石继承问题
    print("\n4. 钻石继承分析:")
    try:
        for cls in [Bat, Dolphin, Duck, Penguin]:
            diamonds = MROAnalyzer.find_diamond_inheritance(cls)
            if diamonds:
                print(f"{cls.__name__} 存在钻石继承: {[c.__name__ for c in diamonds]}")
            else:
                print(f"{cls.__name__} 无钻石继承问题")
    
    except Exception as e:
        print(f"钻石继承分析出错: {e}")
    
    print("\n=== 多重继承和MRO演示完成 ===")


if __name__ == "__main__":
    demonstrate_multiple_inheritance()
